package my.hw;

import java.util.ArrayList;
import java.util.List;

import android.graphics.Point;

public abstract class AbstractRule<TColor> {
    private Point[] vectors= {
        new Point(1,  0), new Point(-1,  0), // 左右
        new Point(0,  1), new Point(0,  -1), // 
        new Point(1,  1), new Point(-1, -1),
        new Point(1, -1), new Point(-1,  1)
    };

    private static Point PosAdd(Point pos, Point vec) {
        return new Point(pos.x + vec.x, pos.y + vec.y);
    }
    
//    private boolean isReverseColor(Point pos1, Point pos2) {
//      if (!isEmpty(pos1)) return false;
//      if (!isEmpty(pos2)) return false;
//        return !isSameColor(pos1, pos2);
//    }    
    
    protected abstract boolean isReverseColor(Point pos, TColor color);
    
    protected abstract boolean isEmpty(Point pos);
    
    protected abstract boolean isLegal(Point pos);
    
    // if false return new Point[]{}
    public Point[] judge(TColor color, Point pos) {
        if (!isLegal(pos)) return new Point[]{};
        if (!isEmpty(pos)) return new Point[]{};
        
        List<Point> lst_pos_total= new ArrayList<Point>();
        
        for(Point vec : vectors) {
            // 方向對應的第一個點必須不同顏色
            //同顏色無法下 不同顏色必須判定後一個或後後一個到最後一個為同顏色才可下
            Point pos_first= PosAdd(pos, vec);
            if (!isLegal(pos_first)) continue;
            if (isEmpty(pos_first)) continue;
            if (!isReverseColor(pos_first, color)) continue;
            
            List<Point> lst_pos_vec= new ArrayList<Point>();
            for (Point pos2= pos_first; true; pos2= PosAdd(pos2, vec)) {
                if (!isLegal(pos2)) break;
                if (isEmpty(pos2)) break;
                if (!isReverseColor(pos2, color)){ // 回來了
                    lst_pos_total.addAll(lst_pos_vec);
                    break;
                }
                // if isReverseColor
                lst_pos_vec.add(pos2);
            }
        }
        
        return lst_pos_total.toArray(new Point[lst_pos_total.size()]);
    }
    
    
    
    
    
    
}